﻿//======================================================================
//
//	Cross-Platform XNA Menu System
//  http://cpxms.codeplex.com/
//
//  All code and content licensed under Microsoft Public License (Ms-PL)	
//
//======================================================================
//
//	File:		Attributes.cs
//
//	Author:		MJP
//
//	Date:		04/23/09
//
//======================================================================

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Xml.Serialization;
using System.Drawing.Design;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace CPXMenu
{
    /// <summary>
    /// Used to indicate whether the type supports having child items
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class CanHaveChildrenAttribute : Attribute
    {
        bool canHaveChildren = false;

		/// <summary>
		/// Gets a value indicating whether or not the bound Type can 
		/// have children.
		/// </summary>
        public bool CanHaveChildren
        {
            get { return canHaveChildren; }
        }

		/// <summary>
		/// Creates a CanHaveChildrenAttribute instance
		/// </summary>
		/// <param name="canHaveChildren">Indicates whether or not the bound type can have children</param>
        public CanHaveChildrenAttribute(bool canHaveChildren)
        {
            this.canHaveChildren = canHaveChildren;
        }
    }

	/// <summary>
	/// Used to set the icon key for the type, which is used to look
	/// up the icon in the global icon ImageList
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class IconKeyAttribute : Attribute
    {
        public const string DefaultIconKey = "Control";

        string iconKey = DefaultIconKey;

		/// <summary>
		/// Gets a value indicating the icon key for the bound Type
		/// </summary>
        public string IconKey
        {
            get { return iconKey; }
        }

		/// <summary>
		/// Creates an IconKeyAttribute instance
		/// </summary>
		/// <param name="iconKey">The key of the icon in the global icon ImageList</param>
        public IconKeyAttribute(string iconKey)
        {
            this.iconKey = iconKey;
        }
    }

	/// <summary>
	/// Used to indicate whether the Type is selectable at
	/// design-time
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class SelectableAttribute : Attribute
    {
        bool selectable = false;

		/// <summary>
		/// Gets a value indicating whether the Type is selectable at
		/// design-time
		/// </summary>
        public bool Selectable
        {
            get { return selectable; }
        }

		/// <summary>
		/// Creates a SelectableAttribute instance
		/// </summary>
		/// <param name="selectable">A value indicating whether the Type is selectable at
		/// design-time</param>
        public SelectableAttribute(bool selectable)
        {
            this.selectable = selectable;
        }
    }

	/// <summary>
	/// Can be used to specify that a Type can only be added
	/// to a specific parent type.  If this Attribute is not
	/// applied or has ParentType == null, then the Type
	/// can be added as a child to any Type that doesn't
	/// explicitly specify a required child Type.
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class ParentTypeAttribute : Attribute
    {
        Type parentType = null;

		/// <summary>
		/// Gets the required parent Type of the bound Type, or null if none specified
		/// </summary>
        public Type ParentType
        {
            get { return parentType; }
        }

		/// <summary>
		/// Creates a ParentTypeAttribute instance
		/// </summary>
		/// <param name="parentType">the required parent Type of the bound Type, or null if none specified</param>
        public ParentTypeAttribute(Type parentType)
        {
            this.parentType = parentType;
        }
    }

	/// <summary>
	/// Can be used to specify that a Type can only have instances
	/// of a specific type as its children.  If this Attribute is not
	/// applied or has ChildType == null, then the Type
	/// can have as a child any Type that doesn't
	/// explicitly specify a required parent Type.
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class ChildTypeAttribute : Attribute
    {
        Type childType = null;

		/// <summary>
		/// Gets the specified child Type, or null if none specified
		/// </summary>
        public Type ChildType
        {
            get { return childType; }
        }

		/// <summary>
		/// Creates a ChildTypeAttribute instance
		/// </summary>
		/// <param name="childType">the specified child Type, or null if none specified</param>
        public ChildTypeAttribute(Type childType)
        {
            this.childType = childType;
        }
    }

	/// <summary>
	/// Used to indicate whether a Type can be moved at design-time
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class MovableAttribute : Attribute
    {
        bool movable = false;

		/// <summary>
		/// Gets a value indicating whether a Type can be moved at design-time
		/// </summary>
        public bool Movable
        {
            get { return movable; }
        }

		/// <summary>
		/// Creates a new instance of MovableAttribute
		/// </summary>
		/// <param name="movable">a value indicating whether a Type can be moved at design-time</param>
        public MovableAttribute(bool movable)
        {
            this.movable = movable;
        }
    }

	/// <summary>
	/// Used to indicate whether a Type can be sized at design-time
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class SizeableAttribute : Attribute
    {
        bool sizeable = false;

		/// <summary>
		/// Gets a value indicating whether a Type can be sized at design-time
		/// </summary>
        public bool Sizeable
        {
            get { return sizeable; }
        }

		/// <summary>
		/// Creates a new instance of SizeableAttribute
		/// </summary>
		/// <param name="movable">a value indicating whether a Type can be sized at design-time</param>
        public SizeableAttribute(bool sizeable)
        {
            this.sizeable = sizeable;
        }
    }

	/// <summary>
	/// Used to indicate whether a Type can be copy/cut/pasted at design-timee
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class CanCopyPasteAttribute : Attribute
    {
        bool canCopyPaste = false;

		/// <summary>
		/// Gets a value indicating whether a Type can be copy/cut/pasted at design-timee
		/// </summary>
        public bool CanCopyPaste
        {
            get { return canCopyPaste; }
        }

		/// <summary>
		/// Creates a new instance of CanCopyPasteAttribute
		/// </summary>
		/// <param name="canCopyPaste">a value indicating whether a Type can be copy/cut/pasted at design-timee</param>
        public CanCopyPasteAttribute(bool canCopyPaste)
        {
            this.canCopyPaste = canCopyPaste;
        }
    }

	/// <summary>
	/// Used to specify the category that the bound Type belongs to
	/// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class ItemCategoryAttribute : Attribute
    {
        string category = DefaultCategory;

        public const string DefaultCategory = "Misc";

		/// <summary>
		/// Gets the category that the bound Type belongs to
		/// </summary>
        public string Category
        {
            get { return category; }
        }

		/// <summary>
		/// Creates a new instance of ItemCategoryAttribute
		/// </summary>
		/// <param name="category">the category that the bound Type belongs to</param>
        public ItemCategoryAttribute(string category)
        {
            this.category = category;
        }
    }

    /// <summary>
    /// Used to specify whether a Type can have focus
    /// </summary>
    [AttributeUsage(AttributeTargets.Class)]
    internal class CanHaveFocusAttribute : Attribute
    {
        bool canHaveFocus = false;

        /// <summary>
        /// Gets a value indicating whether the bound Type can have focus
        /// </summary>
        public bool CanHaveFocus
        {
            get { return canHaveFocus; }
        }

        /// <summary>
        /// Creates a new instance of CanHaveFocusAttribute
        /// </summary>
        /// <param name="canHaveFocus">a value indicating whether the bound Type can have focus</param>
        public CanHaveFocusAttribute(bool canHaveFocus)
        {
            this.canHaveFocus = canHaveFocus;
        }
    }
}